package com.example.bilibili_miaosha.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.bilibili_miaosha.config.AccessLimit;
import com.example.bilibili_miaosha.entity.Goods;
import com.example.bilibili_miaosha.entity.Order;
import com.example.bilibili_miaosha.entity.SeckillOrder;
import com.example.bilibili_miaosha.entity.User;
import com.example.bilibili_miaosha.service.IGoodsService;
import com.example.bilibili_miaosha.service.IOrderService;
import com.example.bilibili_miaosha.service.ISeckillOrderService;
import com.example.bilibili_miaosha.service.IUserService;
import com.example.bilibili_miaosha.utils.CookieUtil;
import com.example.bilibili_miaosha.vo.GoodsVO;
import com.example.bilibili_miaosha.vo.RespBean;
import com.example.bilibili_miaosha.vo.RespBeanEnum;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName secKillController
 * @Description TODO
 * @Author 川
 * @Date 2022/4/2 17:11
 * @Version 1.0
 **/
@Slf4j
@Controller
@RequestMapping("/seckill")
public class secKillController {
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private ISeckillOrderService seckillOrderService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("/doSeckill2")
    public String doSeckill2(Model model, User user, Long goodsId, HttpServletRequest request) {

        if (user == null) {
            return "login";
        }
        model.addAttribute("user", user);
        GoodsVO goodsVO = goodsService.findGoodsVoByGoodsId(goodsId);
        if (goodsVO.getStockCount() < 1) {
            model.addAttribute("errmsg", RespBeanEnum.EMPTY_STOCK);
            return "seckillFail";
        }
        //判断是否重复抢购  同一个人购买同一件商品 -->秒杀订单表中这个人&商品出现了两次
        //普通数据库中存取
//        SeckillOrder seckillOrder = seckillOrderService.getOne(new QueryWrapper<SeckillOrder>().eq("user_id", user.getId()).eq("goods_id", goodsId));
        SeckillOrder seckillOrder = (SeckillOrder) redisTemplate.opsForValue().get("order:" + user.getId() + ":" + goodsId);
        if (seckillOrder != null) {
            model.addAttribute("errmsg", RespBeanEnum.REPEAT_ERROR);
            return "seckillFail";
        }
        //成功抢购的流程
        Goods goods = goodsService.getById(goodsId);
        Order order = orderService.seckill(user, goods);
        model.addAttribute("order", order);
        model.addAttribute("goods", goods);
        return "orderDetail";

    }

    @AccessLimit(second = 5,needLogin = true,maxCount = 5)
    @RequestMapping("/doSeckill")
    @ResponseBody
    public RespBean doSeckill(User user, @RequestParam Long goodsId, @RequestParam String captcha, HttpServletRequest request) {//todo：这个goodsID经常接收不到
//        System.out.println("接收到的goodsId" + goodsId);
        if (user == null) {
            return RespBean.error(RespBeanEnum.LOGIN_ERROR);
        }
        /*被前面的@AccessLimit(second = 5,needLogin = true,maxCount = 5)取代了
        //接口限流
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //限制访问次数，5秒内访问5次
        String uri = request.getRequestURI();
        //方便测试
        captcha = "0";
        Integer count = (Integer) valueOperations.get(uri + ":" + user.getId());
        if (count == null) {
            valueOperations.set(uri + ":" + user.getId(), 1, 5, TimeUnit.SECONDS);
        } else if (count < 5) {
            valueOperations.increment(uri + ":" + user.getId());
        } else {
            return RespBean.error(RespBeanEnum.ACCESS_LIMIT_REACHED);
        }*/
        //校验二维码
        boolean check = orderService.checkCaptcha(user, goodsId, captcha);
        if (!check) {
            return RespBean.error(RespBeanEnum.ERROR_CAPTCHA);
        }

        GoodsVO goodsVO = goodsService.findGoodsVoByGoodsId(goodsId);
        if (goodsVO == null || goodsVO.getStockCount() < 1) {
            return RespBean.error(RespBeanEnum.EMPTY_STOCK);
        }
        //判断是否重复抢购  同一个人购买同一件商品 -->秒杀订单表中这个人&商品出现了两次
        SeckillOrder seckillOrder = seckillOrderService.getOne(new QueryWrapper<SeckillOrder>().eq("user_id", user.getId()).eq("goods_id", goodsId));
        if (seckillOrder != null) {
            return RespBean.error(RespBeanEnum.REPEAT_ERROR);
        }
        //成功抢购的流程
        Goods goods = goodsService.getById(goodsId);
        Order order = orderService.seckill(user, goods);
        order.setId(order.getId());
        return RespBean.success(order);

    }

    //    @RequestMapping(name = "/captcha",method = RequestMethod.GET)   不能用name
    @RequestMapping(value = "/captcha", method = RequestMethod.GET)
    public void verifyCode(User user, Long goodsId, HttpServletResponse response) {
        //健壮性判断
        if (user == null || goodsId < 0) {
            System.out.println("验证码处用户信息or商品信息出错");
            return;
        }
        // 设置请求头为输出图片类型
        response.setContentType("image/jpg");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 三个参数分别为宽、高、位数
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 32, 5);

        // 验证码存入session
//        request.getSession().setAttribute("captcha", specCaptcha.text().toLowerCase());
        //验证码存到了redis
        redisTemplate.opsForValue().set("captcha:" + user.getId() + ":" + goodsId, specCaptcha.text(), 300, TimeUnit.SECONDS);
        System.out.println("captcha:" + user.getId() + ":" + goodsId + "->" + specCaptcha.text());
        // 输出图片流
        try {
            specCaptcha.out(response.getOutputStream());
        } catch (IOException e) {
            log.error("验证码生成失败");  //@sl4j才可以用的
        }
    }

    @RequestMapping(value = "/path", method = RequestMethod.GET) //没有使用这个隐藏地址
    @ResponseBody
    public RespBean getPath(User user, Long goodsId, String captcha) {
        if (user == null) {
            return RespBean.error(RespBeanEnum.SESSION_ERROR);
        }
        boolean check = orderService.checkCaptcha(user, goodsId, captcha);
        if (!check) {
            return RespBean.error(RespBeanEnum.ERROR_CAPTCHA);
        }
        String str = orderService.createPath(user, goodsId);
        return RespBean.success(str);
    }
}
